package dao

import (
	"context"
	"coolcar/v1/shared/ids"
	"coolcar/v1/shared/mgutils"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

var (
	dbFieldName     = "account"
	openIDFieldName = "open_id"
	idFieldName     = "_id"
)

// Mongo defines a mongo dao.
type Mongo struct {
	col *mongo.Collection
}

// NewMongo return an account collection from the mongodb.
func NewMongo(db *mongo.Database) *Mongo {
	return &Mongo{col: db.Collection(dbFieldName)}
}

// ResolveAccountID resolves an account id from openid.
func (m *Mongo) ResolveAccountID(ctx context.Context, openID string) (ids.AccountID, error) {
	filter := bson.M{
		openIDFieldName: openID,
	}
	update := mgutils.SetOnInsert(bson.M{
		idFieldName:     mgutils.NewObjID(),
		openIDFieldName: openID,
	})
	res := m.col.FindOneAndUpdate(ctx, filter, update, options.FindOneAndUpdate().
		SetUpsert(true).SetReturnDocument(options.After))

	if err := res.Err(); err != nil {
		return "", err
	}

	var row mgutils.IDField
	err := res.Decode(&row)
	if err != nil {
		return "", err
	}
	return ids.AccountID(row.ID.Hex()), nil
}
